/**
 * Created by henian.xu on 2019/10/3.
 *
 */

import Vue from 'vue';
import Router from 'router';

const vm = new Vue();
const recordRequestMap = {};
const recordLoadingMap = {};

// 获取取消请求配置
export function getExtendConfig(config) {
  const { cancelToken } = config;
  if (!cancelToken || !cancelToken.extendConfig) return null;
  return cancelToken.extendConfig;
}

// 记录请求用于处理重复请求
function recordRequest(config) {
  const extendConfig = getExtendConfig(config);
  if (!extendConfig) return;
  const { isRepeat, isCancelBefore, cancelSource } = extendConfig;
  if (isRepeat) return; // 可重复的请求不记录
  const { url, baseURL } = config;
  const recordKey = `${baseURL}${url}`;
  const oldCancelSource = recordRequestMap[recordKey];
  if (!oldCancelSource) {
    // requestMap 无记录说明是新的请求
    recordRequestMap[recordKey] = cancelSource;
  } else if (isCancelBefore) {
    oldCancelSource.cancel(`因重复而取消之前的请求:${recordKey}`);
    recordRequestMap[recordKey] = cancelSource; // 更新取消令牌
  } else {
    cancelSource.cancel(`因重复而取消当前的请求:${recordKey}`);
  }
}

// 删除已记录的请求
function removeRequestRecord(response) {
  const { config } = response;
  if (!config || !config.url) return;
  const { url, baseURL } = config;
  const recordKey = new RegExp(`^${baseURL}`).test(url)
    ? url
    : `${baseURL}${url}`;
  delete recordRequestMap[recordKey];
}

// 请求提示处理
function promptHandler(response) {
  const { config, data: result } = response;
  const extendConfig = getExtendConfig(config);
  if (!extendConfig) return Promise.resolve(response);
  const { isHandleError, isSuccessTip } = extendConfig;
  if (result.error_code) {
    if (isHandleError) return Promise.resolve(response);
    // 统一处理失败请求提示
    vm.$messageBox.alert(result.error_msg);
    return Promise.reject(response);
  }
  if (isSuccessTip) {
    // 统一处理成功请求提示
    vm.$messageBox.tips(result.msg);
  }
  return Promise.resolve(response);
}

// loading处理
function recordRequestLoading(config) {
  const extendConfig = getExtendConfig(config);
  if (!extendConfig) return;
  const { isLoading } = extendConfig;
  if (!isLoading) return;
  const { url, baseURL } = config;
  const recordKey = `${baseURL}${url}`;
  recordLoadingMap[recordKey] = true;
  vm.$nprogress.start();
}
function removeRequestLoading(response) {
  const { config } = response;
  if (!config || !config.url) return;
  const { url, baseURL } = config;
  const recordKey = new RegExp(`^${baseURL}`).test(url)
    ? url
    : `${baseURL}${url}`;
  delete recordLoadingMap[recordKey];
  const { length } = Object.keys(recordLoadingMap);
  if (length) return;
  vm.$nprogress.done();
}

const httpStatusHandler = {
  isStatusProcessing: {
    401: false,
  },
  401() {
    console.log(401);
    if (this.isStatusProcessing['401']) return;
    Router.replace('/login');
  },
  404(/* response */) {
    // console.log('404');
  },
};

// http状态处理
function httpStatusCodeHandler(error) {
  const { response } = error || {};
  if (!response || !+response.status) return;
  const { /* config, */ status } = response;
  // const extendConfig = getExtendConfig(config);
  // if (extendConfig && extendConfig.isHandleError) return;
  if (httpStatusHandler[status]) httpStatusHandler[status](response);
}

//* *-- 导出方法 --**//

/**
 * 请求成功拦截
 * @param config
 */
export function requestSuccess(config) {
  recordRequestLoading(config);
  recordRequest(config);
  return config;
}

/**
 * 请求失败拦截
 * @param error
 */
export function requestFail(/* error */) {}

/**
 * 响应成功拦截 status === 200
 * @param response
 */
export function responseSuccess(response) {
  removeRequestRecord(response);
  removeRequestLoading(response);
  return promptHandler(response);
}

/**
 * 响应失败拦截 status !== 200
 * @param error
 */
export function responseFail(error) {
  removeRequestRecord(error);
  removeRequestLoading(error);
  httpStatusCodeHandler(error);
  return Promise.reject(error);
}
